//
//  ZMKNormalTextField.swift
//  UIKitExtentions
//
//  Created by gupengling on 2021/7/29.
//

import UIKit
public typealias TextFieldTapBlock = (_ sender: AnyObject?) -> Void

@objcMembers public class ZMKNormalTextFieldConfig: NSObject {
    var space: CGFloat = 10.0
    var rightViewWidth: CGFloat = 26.0
    var textSpace: CGFloat = 20.0
    let clearBtnWidth: CGFloat = 20.0

    public convenience init(space: CGFloat, rightWidth: CGFloat, textSpace: CGFloat) {
        self.init()
        self.space = space
        self.rightViewWidth = rightWidth
        self.textSpace = textSpace
    }
}

@objcMembers public class ZMKNormalTextField: UITextField {
    public var config = ZMKNormalTextFieldConfig()
    public let rightNormalView = UIView()

    public var singleTapBlock: TextFieldTapBlock? {
        didSet {
            endEditing(false)
            let singleTap = UITapGestureRecognizer(target:self, action: #selector(handleSingleTap(tap:)))
            addGestureRecognizer(singleTap)
        }
    }

    public override init(frame: CGRect) {
        super.init(frame: frame)
        leftView = rightNormalView
    }

    convenience init() {
        self.init(frame: .zero)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    public override func layoutSubviews() {
        super.layoutSubviews()
    }

    @objc public func showRightView(_ show: Bool) {
        if show {
            leftViewMode = .always
        } else {
            leftViewMode = .never
        }
    }

    @objc public func setPlaceHolderString(_ text: String, _ color: UIColor? = nil, _ textFont: UIFont? = nil) {
        let attrString = NSAttributedString(string: text,
                                            attributes:
                                                [NSAttributedString.Key.foregroundColor : color ?? .lightGray,
                                                 NSAttributedString.Key.font: textFont ?? self.font as Any
                                            ])
        attributedPlaceholder = attrString
    }

    @objc private func handleSingleTap(tap:UITapGestureRecognizer) {
        singleTapBlock?(self)
    }

    private func rightWidth() -> CGFloat {
        if leftViewMode != .never {
            return config.rightViewWidth
        }
        return 0.0
    }

    private func rightClearWidth() -> CGFloat {
        var width: CGFloat = 0.0
        if leftViewMode != .never {
            width += config.rightViewWidth
        }
        width += config.space
        width += config.clearBtnWidth
        return width
    }

    private func textWidth() -> CGFloat {
        var width: CGFloat = 0.0
        if leftViewMode != .never {
            width += config.rightViewWidth
            width += config.space
        }

        if clearButtonMode != .never {
            if width == 0.0 {
                width += config.space
            }
            width += config.clearBtnWidth
            width += config.space
        }

        if width == 0.0 {
            width += config.textSpace
        }
        return width
    }

    public override func clearButtonRect(forBounds bounds: CGRect) -> CGRect {
        return CGRect(x: bounds.origin.x + bounds.size.width - rightClearWidth(), y: bounds.origin.y, width: config.clearBtnWidth, height: bounds.size.height)
    }

    public override func leftViewRect(forBounds bounds: CGRect) -> CGRect {
        return CGRect(x: bounds.size.width - config.rightViewWidth, y: bounds.origin.y, width: config.rightViewWidth, height: bounds.size.height)
    }

    public override func textRect(forBounds bounds: CGRect) -> CGRect {
        return CGRect(x: bounds.origin.x + config.textSpace, y: bounds.origin.y, width: bounds.size.width - textWidth() - config.textSpace, height: bounds.size.height)
    }

    public override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return CGRect(x: bounds.origin.x + config.textSpace, y: bounds.origin.y, width: bounds.size.width - textWidth() - config.textSpace, height: bounds.size.height)
    }
}
